﻿using System;

/***
 *  获取设备的主板ID、CPUID、物理网卡MAC,并进行加密。
 *  加密方式：先将主板ID与CPUID进行异或运算，将得出的结果在于MAC进行异或，最后将结果进行SHA256加密、
 *  
 *  方法：
 *  1.获取设备的主板ID、CPUID、物理网卡MAC,并进行加密。
 *  2.对两个字符串进行异或操作。字符串将会同步长度为64。
 *  3.对两个字符数组进行异或操作。字符数组将会进行长度统一，在较短的字符数组后补'F',直到与较长的字符数组长度相同
 *  
 *  时间：2021.11.24
 *	版本：1.0
 *	作者：李勇
 *	变更描述：创建
 */

namespace HardwareInfo
{
    public static class Verify
    {         
        /// <summary>
        /// 获取主板ID，CPUID，物理网卡MAC地址，进行异或运算并进行SHA256加密，生成验证码
        /// </summary>
        /// <returns>生成的验证码</returns>
 
        public static string GetAuthorizationcode()
        {            
            //cpuid
            string CPUID = HardwareInfoHelper.GetCpuID();            

            //主板id
            string mainboardid = HardwareInfoHelper.GetMainBoardID();

            //物理网卡MAC地址
            string mac = HardwareInfoHelper.GetLocaNetWorkMAC();

            string xor1 = StringXOR(CPUID, mainboardid);

            string xor2 = StringXOR(xor1, mac);

            string str = Encryption.Sha256String(xor2);

            return str;
        }

        /// <summary>
        /// 对两个字符串进行异或操作，字符串长度会以64进行计算
        /// 当字符串长度不足时将在末尾添加截取的默认字符串
        /// </summary>
        /// <param name="str1"></param>
        /// <param name="str2"></param>
        /// <returns></returns>
        public static string StringXOR(string str1, string str2)
        {
            //当字符串为空时使用的默认数据,长度为64
            string df = "hebeihuawowtongxinkejiyouxiangongsi-hebeishengshijiazhuangshi";

            //存放计算好的数
            string s;
            char[] char1, char2, xor;

            //判断字符串是否为空，为空则赋默认值
            if (string.IsNullOrEmpty(str1))
            {
                str1 = df;
            }
            else if(string.IsNullOrEmpty(str2))
            {
                str2 = df;
            }

            #region 对字符串长度进行处理
            //对字符串长度进行处理，
            int len1 = str1.Length;
            int len2 = str2.Length;

            if (len1>=df.Length)
            {
                str1 = str1.Substring(0, df.Length);
            }
            else
            {
                str1 += df.Substring(str1.Length);
            }
            
            if (len2>=df.Length)
            {
                str2 = str2.Substring(0, df.Length);
            }
            else
            {
                str2 += df.Substring(str2.Length);
            }

            #endregion

            //将字符串转换为字符数组
            char1 = str1.ToCharArray();
            char2 = str2.ToCharArray();            

            xor = CharArrayXOR(char1, char2);
            s = xor.ToString();
            return s;
        }

        /// <summary>
        /// 对两个字符数组进行异或操作
        /// 两个字符数组长度不等是，将在短字符串的末尾不‘F’来统一两个字符数组的长度
        /// </summary>
        /// <param name="arr1"></param>
        /// <param name="arr2"></param>
        /// <returns></returns>
        public static char[] CharArrayXOR(char[] arr1, char[] arr2)
        {
            char[] xor;
            int len, len1, len2;

            if (arr1.Length == 0 || arr2.Length == 0)
            {
                throw new Exception("数组长度不能为0");
            }

            len1 = arr1.Length;
            len2 = arr2.Length;

            #region 对两个字符数组统一长度

            len = len1 > len2 ? len1 : len2;

            if (len1 != len)
            {
                for (int i = len1; i < len; i++)
                {
                    arr1[i] = 'F';
                }
            }
            if (len2 != len)
            {
                char[] buff = arr2;
                arr2 = new char[len];
                buff.CopyTo(arr2, 0);

                for (int i = len2; i < len; i++)
                {
                    arr2[i] = 'F';
                }
            }

            #endregion

            xor = new char[len];

            //进行异或运算
            for (int i = 0; i < len; i++)
            {
                xor[i] = (char)(arr1[i] ^ arr2[i]);
            }
            return xor;
        }

        

    }
}
